package zisu.netty.practice.NIO.GroupChat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;

/**
 * @Desc: "一个Socket 客户端"
 * @Author: caixiang
 * @DATE: 2020/7/3 10:33
 */
public class GroupChatClient {
    //定义相关属性
    private final String HOST = "127.0.0.1"; //服务器IP
    private final int PORT = 6667;  //服务器端口
    private Selector selector;
    private SocketChannel socketChannel;
    private String userName;

    //构造器 ,, 完成初始化操作
    public GroupChatClient() throws IOException {
        selector = Selector.open();
        //连接服务器
        socketChannel = SocketChannel.open(new InetSocketAddress(HOST, PORT));
        //设置非阻塞
        socketChannel.configureBlocking(false);
        //把socketChannel 注册到selector   ,,出发事件为读事件
        socketChannel.register(selector, SelectionKey.OP_READ);
        //得到UserName
        userName = socketChannel.getLocalAddress().toString().substring(1);
        System.out.println(userName+"is ok");
    }

    //向服务器发送消息
    public void sendInfo(String info){
        info = userName +" 说："+info;
        try {
            socketChannel.write(ByteBuffer.wrap(info.getBytes()));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //读取从服务器端回复的消息
    public void readInfo(){
        try {
            int read = selector.select();
            if(read>0){  //有read 事件 的通道
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    if(key.isReadable()){
                        //得到相关通道
                        SocketChannel sc = (SocketChannel) key.channel();

                        //得到一个buffer
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        //读取
                        sc.read(buffer);
                        //把读到缓存数据 转成字符串
                        String res = new String(buffer.array());
                        System.out.println(res.trim());
                    }
                }
                //如果不remove。那么当一次发送结束后，再次发送 server端收不到消息。。目的是防止 重复操作。
                //（重要）如果不remove 那么上一次 的事件触发 还在的 ，所以selector.select() 不会阻塞住，会一直报0，然后会一直走else，
                //    尽管新事件进来了，但是read 还是显示0 ( 因为上次的Events 已近处理完了 所以read==0，而现在又有新的事件过来
                //    那么selector.select();就不会阻塞住，就会放行，放进来就是死循环了。。 )
                // remove要配合selector.select();使用
                iterator.remove();
            }/*else {
                System.out.println("没有可用的通道....");
            }*/
        }catch (Exception e){

        }
    }

    public static void main(String[] args) throws IOException {
        //启动我们的客户端
        GroupChatClient chatClient = new GroupChatClient();
        //启动一个线程,,每隔3秒 ，读取从服务器发送过来的数据。。
        new Thread() {
            public void run() {

                while (true) {
                    chatClient.readInfo();
                    try {
                        Thread.currentThread().sleep(3000);
                    }catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        //发送数据给服务器端
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            String s = scanner.nextLine();
            chatClient.sendInfo(s);
        }

    }
}
